{
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.8-final"
  },
  "orig_nbformat": 2,
  "kernelspec": {
   "name": "python37864bit9859aadc2f9b4163a401bc1d107b5e60",
   "display_name": "Python 3.7.8 64-bit"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2,
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "'spam eggs'"
     },
     "metadata": {},
     "execution_count": 1
    }
   ],
   "source": [
    "\"\"\"\n",
    "除了数字，Python 也可以操作字符串。字符串有多种形式，可以使用单引号（'...'），双引号（\"...\"）都可以获得同样的结果 2。反斜杠 \\ 可以用来转义:\n",
    "\"\"\"\n",
    "'spam eggs'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "\"doesn't\""
     },
     "metadata": {},
     "execution_count": 2
    }
   ],
   "source": [
    "'doesn\\'t' # 使用转义符来表示 ' 的原始意义"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "\"dosen't\""
     },
     "metadata": {},
     "execution_count": 3
    }
   ],
   "source": [
    "\"dosen't\" # 可以使用双引号来表示 单引号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "'\"yes\",they said'"
     },
     "metadata": {},
     "execution_count": 4
    }
   ],
   "source": [
    "'\"yes\",they said' # 用 单双引号来区别"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "'\"yes,\"they said.'"
     },
     "metadata": {},
     "execution_count": 5
    }
   ],
   "source": [
    "\"\\\"yes,\\\"they said.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "'\"Isn\\'t,\"they said.'"
     },
     "metadata": {},
     "execution_count": 7
    }
   ],
   "source": [
    "'\"Isn\\'t,\"they said.'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "\"Isn't,\"they said.\n"
    }
   ],
   "source": [
    "\"\"\"在交互式解释器中，输出的字符串外面会加上引号，特殊字符会使用反斜杠来转义。 虽然有时这看起来会与输入不一样（外面所加的引号可能会改变），但两个字符串是相同的。 如果字符串中有单引号而没有双引号，该字符串外将加双引号来表示，否则就加单引号。 print() 函数会生成可读性更强的输出，即略去两边的引号，并且打印出经过转义的特殊字符:\"\"\"\n",
    "\n",
    "print('\"Isn\\'t,\"they said.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "'First line. \\nSecond line.'"
     },
     "metadata": {},
     "execution_count": 1
    }
   ],
   "source": [
    "s = 'First line. \\nSecond line.'  #\\n表示新一行\n",
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "First line. \nSecond line.\n"
    }
   ],
   "source": [
    "print(s) # 使用print() 会显示转义后的内容"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "C:\\some\name\n"
    }
   ],
   "source": [
    "'''\n",
    "如果你不希望前置了 \\ 的字符转义成特殊字符，可以使用 原始字符串 方式，在引号前添加 r 即可:\n",
    "'''\n",
    "print('C:\\some\\name')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "C:\\some\\name\n"
    }
   ],
   "source": [
    "print(r'C:\\some\\name')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "\"字符串字面值可以跨行连续输入。一种方式是用三重引号：... 或 '''...'''。字符串中的回车换行会自动包含到字符串中，如果不想包含，在行尾添加一个 \\\\ 即可。如下例:\""
     },
     "metadata": {},
     "execution_count": 6
    }
   ],
   "source": [
    "\"\"\"字符串字面值可以跨行连续输入。一种方式是用三重引号：\"\"\"'...'\"\"\" 或 '''...'''。字符串中的回车换行会自动包含到字符串中，如果不想包含，在行尾添加一个 \\ 即可。如下例:\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "Usage: thingy[OPTIONS]\n    -h              Display this usage message\n    -H hostname     Hostname to connect to\n    \n"
    }
   ],
   "source": [
    "print('''\\\n",
    "Usage: thingy[OPTIONS]\n",
    "    -h              Display this usage message\n",
    "    -H hostname     Hostname to connect to\n",
    "    ''')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "\nUsage: thingy[OPTIONS]\n    -h              Display this usage message\n    -H hostname     Hostname to connect to\n    \n"
    }
   ],
   "source": [
    "# 注意对比没有 \\ 和 有\\的输出结果 --> 第一排是空行\n",
    "print('''\n",
    "Usage: thingy[OPTIONS]\n",
    "    -h              Display this usage message\n",
    "    -H hostname     Hostname to connect to\n",
    "    ''')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "'unununium'"
     },
     "metadata": {},
     "execution_count": 11
    }
   ],
   "source": [
    "'''字符串可以用 + 进行连接（粘到一起），也可以用 * 进行重复:'''\n",
    "3 * 'un' + 'ium'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "'Python'"
     },
     "metadata": {},
     "execution_count": 12
    }
   ],
   "source": [
    "'''相邻的两个或多个 字符串字面值 （引号引起来的字符）将会自动连接到一起.'''\n",
    "'Py'   'thon'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "'Put several strings within parentheses to have them joined together.'"
     },
     "metadata": {},
     "execution_count": 14
    }
   ],
   "source": [
    "'''这个特性在把很长的的字符串拆开分别输入的时候尤其有用'''\n",
    "text = ('Put several strings within parentheses '\n",
    "        'to have them joined together.')\n",
    "text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "output_type": "error",
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-15-8476c0cf1258>, line 3)",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-15-8476c0cf1258>\"\u001b[1;36m, line \u001b[1;32m3\u001b[0m\n\u001b[1;33m    p'thon'\u001b[0m\n\u001b[1;37m          ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "'''只能对两个字面值这样操作，变量或表达式不行:'''\n",
    "p = 'Py'\n",
    "p'thon' # 报错"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "output_type": "error",
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-17-627b818bf4a7>, line 1)",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-17-627b818bf4a7>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m    ('un'*3) 'iun'\u001b[0m\n\u001b[1;37m                 ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "('un'*3) 'iun'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "'python'"
     },
     "metadata": {},
     "execution_count": 19
    }
   ],
   "source": [
    "'''如果你想连接变量，或者连接变量和字面值，可以用 + 号:'''\n",
    "p = 'py'\n",
    "p + 'thon'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "('P', 'n', 'n', 'y', 'Py', 'tho', 'Py', 'on', 'on')"
     },
     "metadata": {},
     "execution_count": 20
    }
   ],
   "source": [
    "'''\n",
    "字符串是可以被 索引 （下标访问）的，第一个字符索引是 0。单个字符并没有特殊的类型，只是一个长度为一的字符串,\n",
    "索引也可以用负数，这种会从右边开始数,注意 -0 和 0 是一样的，所以负数索引从 -1 开始。\n",
    "除了索引，字符串还支持 切片。索引可以得到单个字符，而 切片 可以获取子字符串.\n",
    "注意切片的开始总是被包括在结果中，而结束不被包括。这使得 s[:i] + s[i:] 总是等于 s\n",
    "'''\n",
    "word = 'Python'\n",
    "word[0], word[5], word[-1], word[-5], word[0:2], word[2:5], word[:2], word[4:], word[-2:]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "output_type": "error",
     "ename": "IndexError",
     "evalue": "string index out of range",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-22-612a769a9c7b>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m     12\u001b[0m \u001b[0m对于使用非负索引的切片\u001b[0m\u001b[0;31m，\u001b[0m\u001b[0m如果索引不越界\u001b[0m\u001b[0;31m，\u001b[0m\u001b[0m那么得到的切片长度就是起止索引之差\u001b[0m\u001b[0;31m。\u001b[0m\u001b[0m例如\u001b[0m\u001b[0;31m，\u001b[0m \u001b[0mword\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m \u001b[0m的长度为2\u001b[0m\u001b[0;31m。\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     13\u001b[0m '''\n\u001b[1;32m---> 14\u001b[1;33m \u001b[0mword\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m42\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mIndexError\u001b[0m: string index out of range"
     ]
    }
   ],
   "source": [
    "'''\n",
    "这样理解切片比较合适：\n",
    " +---+---+---+---+---+---+\n",
    " | P | y | t | h | o | n |\n",
    " +---+---+---+---+---+---+\n",
    " 0   1   2   3   4   5   6\n",
    "-6  -5  -4  -3  -2  -1\n",
    "'''\n",
    "'''\n",
    "第一行数标注了字符串 0...6 的索引的位置，第二行标注了对应的负的索引。那么从 i 到 j 的切片就包括了标有 i 和 j 的位置之间的所有字符。\n",
    "\n",
    "对于使用非负索引的切片，如果索引不越界，那么得到的切片长度就是起止索引之差。例如， word[1:3] 的长度为2。\n",
    "'''\n",
    "word[42]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "('on', '')"
     },
     "metadata": {},
     "execution_count": 25
    }
   ],
   "source": [
    "word[4:42], word[42:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "output_type": "error",
     "ename": "TypeError",
     "evalue": "'str' object does not support item assignment",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-26-592697cb9170>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      2\u001b[0m \u001b[0mPython\u001b[0m \u001b[0m中的字符串不能被修改\u001b[0m\u001b[0;31m，\u001b[0m\u001b[0m它们是\u001b[0m \u001b[0mimmutable\u001b[0m \u001b[0m的\u001b[0m\u001b[0;31m。\u001b[0m\u001b[0m因此\u001b[0m\u001b[0;31m，\u001b[0m\u001b[0m向字符串的某个索引位置赋值会产生一个错误\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      3\u001b[0m '''\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mword\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'J'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: 'str' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "'''\n",
    "Python 中的字符串不能被修改，它们是 immutable 的。因此，向字符串的某个索引位置赋值会产生一个错误:\n",
    "'''\n",
    "word[0] = 'J'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "'Jython'"
     },
     "metadata": {},
     "execution_count": 27
    }
   ],
   "source": [
    "'''\n",
    "如果需要一个不同的字符串，应当新建一个:\n",
    "'''\n",
    "'J' + word[1:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "34"
     },
     "metadata": {},
     "execution_count": 28
    }
   ],
   "source": [
    "'''内建函数 len() 返回一个字符串的长度'''\n",
    "\n",
    "s = 'timeissomethingthatwecanneverhedge'\n",
    "len(s)"
   ]
  }
 ]
}